package com.excilys.model;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.Transient;

import org.hibernate.annotations.Type;
import org.joda.time.DateTime;

/**
 * POJO Transaction Abstract class that represents any transactions that can be
 * performed on an account
 * 
 * @author excilys dev : SC
 * @version 1.0
 * 
 */

@SuppressWarnings("serial")
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Transaction implements Serializable {

	@Id
	@GeneratedValue
	protected long transactionId;
	protected double transactionAmount;

	@Transient
	protected TransactionType transactionType;

	@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
	protected DateTime transactionDate;

	@ManyToOne(optional = false)
	protected Account transactionAccount;

	// ------------------------------------------------------------
	// ------------------------------------------------------------
	// ------------------------------------------------------------

	public Transaction() {
		super();
	}

	public Transaction(double transactionAmount, DateTime transactionDate, Account transactionAccount) {
		super();
		this.transactionAmount = transactionAmount;
		this.transactionDate = transactionDate;
		this.transactionAccount = transactionAccount;
	}

	// ------------------------------------------------------------
	// ------------------------------------------------------------
	// ------------------------------------------------------------

	public abstract String printLabel();

	public String toString() {
		String result = "TransactionId = " + transactionId + "  / TransactionAmount = " + transactionAmount + " / TransactionAccount = " + transactionAccount
				+ " / TransactionDate = " + transactionDate;
		return result;
	}

	public String printDate() {
		return this.getTransactionDate().toString("MM/dd/yy");
	}

	// ------------------------------------------------------------
	// ------------------------------------------------------------
	// ------------------------------------------------------------

	public long getTransactionId() {
		return transactionId;
	}

	public void setTransactionId(long transactionId) {
		this.transactionId = transactionId;
	}

	public double getTransactionAmount() {
		return transactionAmount;
	}

	public void setTransactionAmount(double transactionAmount) {
		this.transactionAmount = transactionAmount;
	}

	public DateTime getTransactionDate() {
		return transactionDate;
	}

	public void setTransactionDate(DateTime transactionDate) {
		this.transactionDate = transactionDate;
	}

	public Account getTransactionAccount() {
		return transactionAccount;
	}

	public void setTransactionAccount(Account transactionAccount) {
		this.transactionAccount = transactionAccount;
	}

	public TransactionType getTransactionType() {
		return transactionType;
	}

	public void setTransactionType(TransactionType transactionType) {
		this.transactionType = transactionType;
	}

	@Override
	public int hashCode() {
		int result = 7;
		final int multiplier = 17;
		result = multiplier * result + (transactionAccount == null ? 0 : transactionAccount.hashCode());
		result = multiplier * result + (transactionDate == null ? 0 : transactionDate.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == this)
			return true;
		if (obj instanceof Transaction) {
			Transaction other = (Transaction) obj;

			if (transactionAccount != other.transactionAccount) {
				if (transactionAccount == null || !transactionAccount.equals(other.transactionAccount))
					return false;
			}
			if (transactionDate != other.transactionDate) {
				if (transactionDate == null || !transactionDate.equals(other.transactionDate))
					return false;
			}
			return true;
		}
		return false;
	}

}
